<!DOCTYPE html>
<!--[if lt IE 7]><html lang="en-us" class="ie6"><![endif]-->
<!--[if IE 7]><html lang="en-us" class="ie7"><![endif]-->
<!--[if IE 8]><html lang="en-us" class="ie8"><![endif]-->
<!--[if gt IE 8]><!--><html lang="en-us"><!--<![endif]-->
<head>
    <meta charset="utf-8">
    <title>Online JavaScript beautifier</title>
    <style>
* {
    margin: 0;
    padding: 0;
}
.ie6 div {
    display: none
}
.ie6 #ie6-go-away {
    display: block !important;
}
img {
    border: 0;
    display: block;
    vertical-align: baseline;
}
#blurb {
    width: 260px;
    float: right;
}
#beauty {
    border-top: 1px solid #f6f6f6;
    margin-left: 5px;
    margin-right: 270px;
}
body {
    background: #eee;
}
body, button, select, label {
    font:13px/1.231 arial, sans-serif;
    *font-size:small;
}
select, label {
    font-size: 12px;
}
body, html {
    height: 100%;
    color: #333;
}
textarea {
    color: #444;
    height: 100%;
    width: 100%;
    border: 0;
    font-family: Monaco, Consolas, monospace;
}
.ie7 fieldset#textarea-wrap {
    padding: 5px 0;
}
.ie8 fieldset#textarea-wrap {
    padding: 5px 0 0 5px;
}

fieldset {
    border: 0;
}
ul, li {
    list-style: none;
}
a {
    color: #36d;
}

fieldset#textarea-wrap {
    height: auto;
    position: absolute;
    background: white;
    left: 0;
    top: 0px;
    right: 0;
    bottom: 0;
    display: block;
    margin-left: 5px;
    margin-bottom: 5px;
    margin-right: 270px;
    margin-top: 40px;
    border: 1px solid #ccc;
    border-right: 1px solid #666;
    border-bottom: 1px solid #666;
    padding: 5px;
}
button#submit {
    margin-top: 5px;
    height: 30px;
    line-height: 28px;
    width: 100%;
    border: 1px solid #aaa;
    border-left: 1px solid #666;
    border-top: 1px solid #666;
    -moz-border-radius: 5px;
    -webkit-border-radius: 5px;
    border-radius: 5px;
    -moz-background-clip: padding; -webkit-background-clip: padding-box; background-clip: padding-box;
    background: #ccc;
    background-image: -webkit-gradient(linear, left top, left bottom, from(#EEEEEE), to(#CCCCCC));
    background-image: -webkit-linear-gradient(top, #EEEEEE, #CCCCCC);
    background-image:    -moz-linear-gradient(top, #EEEEEE, #CCCCCC);
    background-image:     -ms-linear-gradient(top, #EEEEEE, #CCCCCC);
    background-image:      -o-linear-gradient(top, #EEEEEE, #CCCCCC);
    background-image:         linear-gradient(top, #EEEEEE, #CCCCCC);
    filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#EEEEEE', EndColorStr='#CCCCCC');
    cursor: pointer;
    color: #444;
}
button#submit em {
    font-size: 11px;
    font-style: normal;
    color: #999;
}

label {
    cursor: pointer;
}

#options {
    margin-top: 5px;
    margin-bottom: 15px;
}
#options li {
    margin-bottom: 4px;
    font-size: 90%;
}
#options select {
    font:13px/1.231 arial, sans-serif;
    padding: 0 5px;
    width: 220px;
}
#tabsize {
    margin-top: 2px;
}
#brace-style {
    margin-bottom: 6px;
}

#blurb h2 {
    font-size: 12px;
    font-weight: bold;
    color: #555;
}
#blurb p {
    line-height: 140%;
    font-size: 11px;
    margin-right: 16px;
    margin-bottom: 11px;
}

#footer {
    font-size: 11px;
    line-height: 140%;
}

#blurb p.me-me-me {
    margin-bottom: 4px;
}
#blurb p.contributors {
    color: #666;
}
#blurb #uses li {
    font-size: 11px;
    margin-bottom: 4px;
    margin-right: 4px;
}
#blurb #uses li.writeme {
    font-style: normal;
    color: #888;
    margin-bottom: 30px;
    line-height: 130%;
}
    </style>
<script src="jquery/jquery.js"></script>
<script src="jquery/jquery.cookie.js"></script>

<script src="beautify.js"></script>
<script src="beautify-html.js"></script>
<script src="tests/sanitytest.js"></script>
<script src="tests/beautify-tests.js"></script>
<script src="unpackers/javascriptobfuscator_unpacker.js"></script>
<script src="unpackers/urlencode_unpacker.js"></script>
<script src="unpackers/p_a_c_k_e_r_unpacker.js"></script>
<script src="unpackers/myobfuscate_unpacker.js"></script>

<script>

var the = {
    beautify_in_progress: false
};

if (/chrome/.test(navigator.userAgent.toLowerCase())) {
    // this dummy function alleviates Chrome large string corruption by
    // probably shoveling the corruption bug to some other area
    //
    //   http://code.google.com/p/chromium/issues/detail?id=100409
    //   http://jsbeautifier.org/chrome-bug/

    String.prototype.old_charAt = String.prototype.charAt;
    String.prototype.charAt = function (n) { return this.old_charAt(n); }
}


function run_tests() {
    var st = new SanityTest();
    run_beautifier_tests(st);
    JavascriptObfuscator.run_tests(st);
    P_A_C_K_E_R.run_tests(st);
    Urlencoded.run_tests(st);
    MyObfuscate.run_tests(st);
    $('#testresults').html(st.results()).show();
}


function any(a, b) {
    return a || b;
}

function read_settings_from_cookie() {
    $('#tabsize').val(any($.cookie('tabsize'), '4'));
    $('#brace-style').val(any($.cookie('brace-style'), 'collapse'));
    $('#detect-packers').attr('checked', $.cookie('detect-packers') !== 'off');
    $('#preserve-newlines').attr('checked', $.cookie('preserve-newlines') !== 'off');
    $('#keep-array-indentation').attr('checked', $.cookie('keep-array-indentation') === 'on');
}

function store_settings_to_cookie() {
    var opts = { expires: 360 };
    $.cookie('tabsize', $('#tabsize').val(), opts);
    $.cookie('brace-style', $('#brace-style').val(), opts);
    $.cookie('detect-packers', $('#detect-packers').attr('checked') ? 'on' : 'off', opts);
    $.cookie('preserve-newlines', $('#preserve-newlines').attr('checked') ? 'on' : 'off', opts);
    $.cookie('keep-array-indentation', $('#keep-array-indentation').attr('checked') ? 'on' : 'off', opts);
}

function unpacker_filter(source) {
    var trailing_comments = '';
    var comment = '';
    var found = false;

    do {
        found = false;
        if (/^\s*\/\*/.test(source)) {
            found = true;
            comment = source.substr(0, source.indexOf('*/') + 2);
            source = source.substr(comment.length).replace(/^\s+/, '');
            trailing_comments += comment + "\n";
        } else if (/^\s*\/\//.test(source)) {
            found = true;
            comment = source.match(/^\s*\/\/.*/)[0];
            source = source.substr(comment.length).replace(/^\s+/, '');
            trailing_comments += comment + "\n";
        }
    } while (found);

    if (P_A_C_K_E_R.detect(source)) {
        source = unpacker_filter(P_A_C_K_E_R.unpack(source))
    }
    if (Urlencoded.detect(source)) {
        source = unpacker_filter(Urlencoded.unpack(source))
    }
    if (JavascriptObfuscator.detect(source)) {
        source = unpacker_filter(JavascriptObfuscator.unpack(source))
    }
    if (MyObfuscate.detect(source)) {
        source = unpacker_filter(MyObfuscate.unpack(source))
    }

    return trailing_comments + source;
}


function beautify() {
    if (the.beautify_in_progress) return;

    store_settings_to_cookie();

    the.beautify_in_progress = true;

    var source = $('#source').val();
    var indent_size = $('#tabsize').val();
    var indent_char = indent_size == 1 ? '\t' : ' ';
    var preserve_newlines = $('#preserve-newlines').attr('checked');
    var keep_array_indentation = $('#keep-array-indentation').attr('checked');
    var brace_style = $('#brace-style').val();

    if ($('#detect-packers').attr('checked')) {
        source = unpacker_filter(source);
    }

    var comment_mark = '<-' + '-';
    var opts = {
                indent_size: indent_size,
                indent_char: indent_char,
                preserve_newlines:preserve_newlines,
                brace_style: brace_style,
                keep_array_indentation:keep_array_indentation,
                space_after_anon_function:true};

    if (source && source[0] === '<' && source.substring(0, 4) !== comment_mark) {
        $('#source').val(
            style_html(source, opts)
        );
    } else {
        var v = js_beautify(unpacker_filter(source), opts);
        $('#source').val(v);
    }

    the.beautify_in_progress = false;
}

$(function() {

    if ($.browser.msie) {
        $('#source').width( $('#textarea-wrap').width() - 10)
                    .height($('#textarea-wrap').height() - 10);
    }

    read_settings_from_cookie();

    var default_text = "// This is just a sample script. Paste your real code here.\nif ('this_is'==/an_example/){of_beautifer();}else{var a=b?(c%d):e[f];}";
    $('#source').val(default_text).bind('click focus', function () {
        if ($(this).val() == default_text) {
            $(this).val('');
        }
    }).bind('blur', function () {
        if ( ! $(this).val()) {
            $(this).val(default_text);
        }
    });
    $(window).bind('keydown', function (e) {
        if (e.ctrlKey && e.keyCode == 13) {
            beautify();
        }
    })
    $('#submit').bind('click', beautify);
    $('select').bind('change', beautify);
});
</script>
</head>
<body>
    <div id="blurb">
      <fieldset id="options">
          <ul>
          <li><select name="tabsize" id="tabsize">
            <option value="1">indent with a tab character</option>
            <option value="2">indent with 2 spaces</option>
            <option value="3">indent with 3 spaces</option>
            <option value="4">indent with 4 spaces</option>
            <option value="8">indent with 8 spaces</option>
          </select></li>
          <li><select id="brace-style">
            <option value="collapse">Braces with control statement</option>
            <option value="expand">Braces on own line</option>
            <option value="end-expand">End braces on own line</option>
          </select></li>
          <li><input class="checkbox" type="checkbox" id="preserve-newlines" /><label for="preserve-newlines"> Preserve empty lines?</label><br /></li>
          <li><input class="checkbox" type="checkbox" id="detect-packers" /><label for="detect-packers"> Detect packers and obfuscators?</label><br /></li>
          <li><input class="checkbox" type="checkbox" id="keep-array-indentation" /><label for="keep-array-indentation"> Keep array indentation?</label></li>
          </ul>
      </fieldset>

      <p><strong>Beautify, unpack or deobfuscate JavaScript, make JSON/JSONP readable, etc.</strong>.</p>

      <p>All of the source code is available on the <a href="https://github.com/einars/js-beautify">github</a>, and we have a command-line version and a python library as well.

      <p>JSBeautifier is — and always will be — completely free and open, and your thanks, flattrs and donations are very heartwarming — thank you all so much!

      <div style="position: relative; height: 40px">
      <form style="position: absolute; left: 3px;" action="https://www.paypal.com/cgi-bin/webscr" method="post">
        <input type="hidden" name="cmd" value="_s-xclick">
        <input type="hidden" name="hosted_button_id" value="TL28UJK2ARCUJ">
        <input style="border:0" type="image" src="http://spicausis.lv/misc/paypal-donate.gif" name="submit" alt="PayPal - The safer, easier way to pay online!">
        <img alt="" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" height="1">
      </form>
      <p style="position: absolute; left: 120px; top: 1px"><a href="http://flattr.com/thing/94550/jsbeautifier-org" target="_blank"><img src="http://api.flattr.com/button/flattr-badge-large.png" alt="Flattr" /></a></p>
      </div>

      <p>Browser extensions and other uses:</p>
      <ul id="uses">

      <li>A <a href="javascript:(function(){s=document.getElementsByTagName('SCRIPT');tx='';sr=[];for(i=0;i<s.length;i++){with(s.item(i)){t=text;if(t){tx+=t;}else{sr.push(src)};}};with(window.open()){document.write('<textarea id=&quot;t&quot;>'+(sr.join(&quot;\n&quot;))+&quot;\n\n-----\n\n&quot;+tx+'</textarea><script src=&quot;http://jsbeautifier.org/beautify.js&quot;></script><script>with(document.getElementById(&quot;t&quot;)){value=js_beautify(value);with(style){width=&quot;99%&quot;;height=&quot;99%&quot;;borderStyle=&quot;none&quot;;}};</script>');document.close();}})();"><strong>bookmarklet</strong></a> (drag it to your bookmarks) by Ichiro Hiroshi to see all scripts used on the page,</li>

      <li style="margin-top: 8px"><strong>Chrome</strong>: <a href="https://github.com/rixth/jsbeautify-for-chrome">jsbeautify-for-chrome</a> by Tom Rix,</li>
      <li><strong>Chrome</strong>: <a href="https://chrome.google.com/webstore/detail/piekbefgpgdecckjcpffhnacjflfoddg">Pretty Beautiful JavaScript</a> by Will McSweeney,</li>
      <li style="margin-top: 8px"><strong>Firefox</strong>: <a href="https://addons.mozilla.org/en-US/firefox/addon/javascript-deminifier/">Javascript deminifier</a> by Ben Murphy,<br>to be used together with the firebug (<a href="https://github.com/benmmurphy/jsdeminifier_xpi/">github</a>),</li>
      <li style="margin-top: 8px"><strong>Safari</strong>: <a href="http://spadin.github.com/js-beautify-safari-extension">Safari extension</a> by Sandro Padin,</li>
      <li style="margin-top: 8px"><strong>Opera</strong>: <a href="https://addons.opera.com/addons/extensions/details/readable-javascript/">Readable JavaScript</a> (<a href="https://github.com/Dither/readable-javascript">github</a>) by Dither,</li>
      <li><strong>Opera</strong>: <a href="https://addons.opera.com/addons/extensions/details/source/">Source</a> extension by Deathamns,</li>
      <li style="margin-top: 12px"><a style="font-weight: bold" href="http://fiddler2.com/">Fiddler</a> proxy: <a href="http://fiddler2.com/Fiddler2/extensions.asp">JavaScript Formatter addon</a>,
      <li><strong>gEdit</strong> <a href="https://github.com/nagaozen/gedit-tunnings/">tips by Fabio Nagao</a>,</li>
      <li><strong>Akelpad</strong> <a href="http://akelpad.sourceforge.net/forum/viewtopic.php?p=11246#11246">extension</a> by Infocatcher,</li>
      <li>Beautifier in <a style="font-weight: bold" href="http://sethmason.com/2011/04/28/jsbeautify-in-emacs.html">Emacs</a> write-up by Seth Mason,</li>
      <li><a style="font-weight:bold" href="http://c9.io">Cloud9</a>, a lovely IDE running in a browser, working in the node/cloud, uses jsbeautifier (<a href="https://github.com/ajaxorg/cloud9">github</a>),</li>
      <li><a style="font-weight:bold" href="http://www.symetronapps.com/shrinker.html">Shrinker</a>, a non-free JavaScript packer for Mac. I&nbsp;haven't used it, so I&nbsp;have no idea if it's any good,</li>
      <li><a style="font-weight:bold" href="http://www.restconsole.com/">REST Console</a>, a request debugging tool for Chrome, beautifies JSON responses (<a href="https://github.com/codeinchaos/rest-console">github</a>).</li>
      <li class="writeme">Doing anything interesting? Write me to einar@jsbeautifier.org and I'll include your link.</li>
      </ul>

      <div id="footer">

          <p class="me-me-me">Written by Einar Lielmanis, <a href="mailto:einar@jsbeautifier.org">einar@jsbeautifier.org</a></p>
          <p class="me-me-me">Python version flourished by <a href="http://github.com/satufk">Stefano Sanfilippo</a>.</p>
          <p class="contributors">with a great help of <a href="http://jason.diamond.name/weblog/">Jason&nbsp;Diamond</a>, Patrick&nbsp;Hof, Nochum&nbsp;Sossonko, Andreas&nbsp;Schneider, Dave&nbsp;Vasilevsky, <a href="http://my.opera.com/Vital/blog/">Vital&nbsp;Batmanov,</a> Ron&nbsp;Baldwin, Gabriel&nbsp;Harrison, <a href="http://shullian.com">Chris&nbsp;J.&nbsp;Shull</a>, <a href="http://mathiasbynens.be/">Mathias Bynens</a> and others.
          </p>

          <p style="text-align:right">
          <a href="#" style="color: #ccc; border-bottom: 1px dashed #ccc; text-decoration: none;" onclick="run_tests(); return false;">Run the tests</a>
          </p>
          <pre id="testresults"></pre>

      </div>

    </div>
    <div id="beauty">
        <button id="submit"><strong>Beautify JavaScript</strong> <em>(ctrl-enter)</em></button>
        <fieldset id="textarea-wrap">
            <textarea id="source"></textarea>
        </fieldset>
    </div>
    <p id="ie6-go-away" style="display:none">IE6. You must be kidding me.</p>
    <script>
        var _gaq = [['_setAccount', 'UA-7409939-1'], ['_trackPageview']];
        (function(d, t) {
            var g = d.createElement(t),
                s = d.getElementsByTagName(t)[0];
            g.src = '//www.google-analytics.com/ga.js';
            s.parentNode.insertBefore(g, s);
        }(document, 'script'));
    </script>
</body>
</html>
